package com.sam.composition;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class CompositionTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		InstrumentedHashSet<String> instrumentedHashSet = new InstrumentedHashSet<String>();
		/** 添加三个元素 **/
		instrumentedHashSet.addAll(Arrays.asList("a", "b", "c"));
		/** 查看添加的元素:结果是6与预期的3不同，原因在于父类addAll实现依赖于add 计数重复加了，实现一个类无法知道这个实现细节 **/
		System.out.println(instrumentedHashSet.getAddCount());



		
		/**服用包装类模式**/
		InstrumentedHashSet2<String> instrumentedHashSet2 = new InstrumentedHashSet2<String>(new HashSet<String>());
		/** 添加三个元素 **/
		instrumentedHashSet2.addAll(Arrays.asList("a", "b", "c"));
		System.out.println(instrumentedHashSet2.getAddCount());



	}

	/**
	 * 类继承实现集合记录总共添加了多少个元素方法！【继承实现】
	 * 
	 * @author sam
	 * @param <E>
	 */
	public static class InstrumentedHashSet<E> extends HashSet<E> {

		private static final long serialVersionUID = 7222590332371778830L;

		private int addCount = 0;

		public InstrumentedHashSet(int initcap, float loadFactior) {

			super(initcap, loadFactior);
		}

		public InstrumentedHashSet() {

		}

		@Override
		public boolean add(E e) {

			addCount++;
			return super.add(e);

		};

		// 注释掉addAll的实现功能正确
		/*
		 * @Override public boolean addAll(Collection<? extends E> c) { addCount
		 * += c.size(); return super.addAll(c); }
		 */

		public int getAddCount() {
			return addCount;
		}

	}

	public static class InstrumentedHashSet2<E> extends ForwardingSet<E> {

		private int addCount;

		public InstrumentedHashSet2(Set<E> set) {
			super(set);
		}

		@Override
		public boolean addAll(Collection<? extends E> c) {

			addCount += c.size();

			return super.addAll(c);
		}

		@Override
		public boolean add(E e) {
			addCount++;
			return super.add(e);

		}

		public int getAddCount() {
			return addCount;
		};

	}

	public static class ForwardingSet<E> implements Set<E> {

		private final Set<E> set;

		public ForwardingSet(Set<E> set) {

			this.set = set;
		}

		@Override
		public int size() {
			// TODO Auto-generated method stub
			return set.size();
		}

		@Override
		public boolean isEmpty() {
			// TODO Auto-generated method stub
			return set.isEmpty();
		}

		@Override
		public boolean contains(Object o) {
			// TODO Auto-generated method stub
			return set.contains(o);
		}

		@Override
		public Iterator<E> iterator() {
			// TODO Auto-generated method stub
			return set.iterator();
		}

		@Override
		public Object[] toArray() {
			// TODO Auto-generated method stub
			return set.toArray();
		}

		@Override
		public <T> T[] toArray(T[] a) {
			// TODO Auto-generated method stub
			return set.toArray(a);
		}

		@Override
		public boolean add(E e) {
			// TODO Auto-generated method stub
			return set.add(e);
		}

		@Override
		public boolean remove(Object o) {
			// TODO Auto-generated method stub
			return set.remove(o);
		}

		@Override
		public boolean containsAll(Collection<?> c) {
			// TODO Auto-generated method stub
			return set.containsAll(c);
		}

		@Override
		public boolean addAll(Collection<? extends E> c) {
			// TODO Auto-generated method stub
			return set.addAll(c);
		}

		@Override
		public boolean retainAll(Collection<?> c) {
			// TODO Auto-generated method stub
			return set.retainAll(c);
		}

		@Override
		public boolean removeAll(Collection<?> c) {
			// TODO Auto-generated method stub
			return set.removeAll(c);
		}

		@Override
		public void clear() {
			// TODO Auto-generated method stub
			set.clear();
		}
	}

}
